using System;
using System.Data;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using Novapangeia.Dominio;
using SharpArch.Data.NHibernate;
using NHibernate.Linq;
using System.Linq;
using NHibernate.Criterion;

namespace Novapangeia.RepositorioNHibernate
{	
	public class RepositorioUsuario : Repository<Usuario>
	{	   
        public IList<Usuario> ListarComerciantesPoderosos()
        {
//            string sql = @"SELECT        usuario.id, usuario.login, usuario.senha, usuario.general, usuario.cidade, usuario.email, usuario.coordenada_X, usuario.coordenada_Y, usuario.score
//                            FROM            usuario INNER JOIN
//                                                     estoque ON estoque.usuario_id = usuario.id
//                            GROUP BY usuario.id
//                            ORDER BY (SELECT count(*) FROM negociacao WHERE negociacao.usuario_ofertante = usuario.id AND negociacao.fechada = 1) DESC, estoque.ouro + estoque.comida + estoque.minerio + estoque.madeira DESC
//                            LIMIT 10";
            var query = Session.CreateQuery(@"select usuario from Usuario as usuario 
                                                    left join usuario.NegociacoesCriadas as negociacoes
                                                    where negociacoes.negociacaoFechada = true
                                                    group by usuario.Id
                                                    order by count(negociacoes)");

            return query.SetMaxResults(10).List<Usuario>();
        }

        public IList<Usuario> ListarTop10Score()
        {
//            string sql = @"SELECT        usuario.id, usuario.login, usuario.senha, usuario.general, usuario.cidade, usuario.email, usuario.coordenada_X, usuario.coordenada_Y, usuario.score
//                            FROM            usuario
//                            ORDER BY usuario.score DESC
//                            LIMIT 10";

            var query = from u in Session.Query<Usuario>()
                        orderby u.Score descending
                        select u;

            return query.Take(10).ToList();
        }

        public IList<Usuario> ListarGeneraisPoderosos()
        {
//            string sql = @"SELECT        usuario.id, usuario.login, usuario.senha, usuario.general, usuario.cidade, usuario.email, usuario.coordenada_X, usuario.coordenada_Y, usuario.score
//                            FROM            usuario INNER JOIN
//                                                     estoque ON estoque.usuario_id = usuario.id INNER JOIN
//                                                     tropa ON usuario.id = tropa.usuario_id INNER JOIN
//                                                     unidade ON tropa.id = unidade.tropa_id
//                            GROUP BY usuario.id
//                            ORDER BY SUM(unidade.quantidade) DESC, estoque.lancas + estoque.espadas + estoque.arcos DESC
//                            LIMIT 10";

            //return Session.QueryOver<Usuario>().OrderBy(u => u.tropas.Sum(t => t.Unidades.Count)).Desc.List();
            //var query = Session.Query<Usuario>().OrderBy(u => u.tropas.Sum(
            //            orderby u.tropas.Sum(x => x.Unidades.Count) descending
            //            select u;
            var query = Session.CreateQuery(@"select usuario from Usuario as usuario 
                                                inner join usuario.tropas as tropa 
                                                inner join tropa.Unidades as unidade
                                              group by usuario.Id
                                              order by sum(unidade.Quantidade) desc");

            return query.SetMaxResults(10).List<Usuario>();
        }
		
        public bool ExisteCoordenada(int coordenada_X, int coordenada_Y)
        {
            //string sql = "select * from usuario where coordenada_x = @p_Coordenada_X and coordenada_y = @p_Coordenada_Y";
            var usuarios = Session.QueryOver<Usuario>().Where(u => u.Cordenada_X == coordenada_X && u.Cordenada_Y == coordenada_Y).List();
            return usuarios.Count != 0;
        }

        public Usuario ConsultarPorNomeSenha(string login, string senha)
        {
            //string sql = @"SELECT id, login, senha, general, cidade, email, coordenada_X, coordenada_Y, score FROM usuario WHERE (login = @p_login and senha = @p_senha)";
            return Session.QueryOver<Usuario>().Where(u => u.Login == login && u.Senha == senha).SingleOrDefault();
        }

        public Usuario ConsultarPorNome(string login)
        {
            return Session.QueryOver<Usuario>().Where(u => u.Login == login).SingleOrDefault();
        }

        public Usuario ConsultarPorCordenadas(int coordenada_X, int coordenada_Y)
        {
            //string sql = "SELECT id, login, senha, general, cidade, email, coordenada_X, coordenada_Y, score from usuario where coordenada_x = @p_Coordenada_X and coordenada_y = @p_Coordenada_Y";
            return Session.QueryOver<Usuario>()
                .Where(u => u.Cordenada_X == coordenada_X && u.Cordenada_Y == coordenada_Y)
                .SingleOrDefault();
        }

        public bool CalcularScoreUsuarios()
        {
            //return sqlHelper.ExecuteSql(CommandType.Text, "call sp_usuario_calcular_score");
            //throw new NotImplementedException();
            var query = Session.CreateSQLQuery("call sp_usuario_calcular_score");
            query.ExecuteUpdate();
            return true;
        }

        public bool ExisteUsuarioNaArea(int xInicio, int xFim, int yInicio, int yFim)
        {
            var query = Session.QueryOver<Usuario>()
                            .Where(x => x.Cordenada_X >= xInicio
                                        && x.Cordenada_X <= xFim
                                        && x.Cordenada_Y >= yInicio
                                        && x.Cordenada_Y <= yFim)
                                        .RowCount();
            return query != 0;
        }

        public IList<Usuario> ListarUsuariosNaArea(int xInicio, int xFim, int yInicio, int yFim)
        {
            var query = Session.QueryOver<Usuario>()
                .Where(x => x.Cordenada_X >= xInicio
                            && x.Cordenada_X <= xFim
                            && x.Cordenada_Y >= yInicio
                            && x.Cordenada_Y <= yFim);

            return query.List();
        }
    }
}
